package org.codehaus.activemq.store.jdbc;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.jms.JMSException;
import javax.transaction.xa.XAException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.activemq.message.ActiveMQXid;
import org.codehaus.activemq.message.WireFormat;
import org.codehaus.activemq.service.Transaction;
import org.codehaus.activemq.service.TransactionManager;
import org.codehaus.activemq.store.PreparedTransactionStore;

public class JDBCPreparedTransactionStore
  implements PreparedTransactionStore
{
  private static final Log log = LogFactory.getLog(JDBCMessageStore.class);
  private final WireFormat wireFormat;
  private final JDBCAdapter adapter;

  public JDBCPreparedTransactionStore(JDBCAdapter adapter, WireFormat wireFormat)
  {
    this.adapter = adapter;
    this.wireFormat = wireFormat;
  }

  public ActiveMQXid[] getXids()
    throws XAException
  {
    List list = new ArrayList();

    Connection c = TransactionContext.getConnection();
    try {
      this.adapter.doGetXids(c, list);
    } catch (SQLException e) {
      log.error("Failed to recover prepared transaction log: " + e, e);
      throw new XAException("Failed to recover container. Reason: " + e);
    }

    ActiveMQXid[] answer = new ActiveMQXid[list.size()];
    list.toArray(answer);
    return answer;
  }

  public void remove(ActiveMQXid xid) throws XAException
  {
    try
    {
      Connection c = TransactionContext.getConnection();
      this.adapter.doRemoveXid(c, xid);
    } catch (SQLException e) {
      throw new XAException("Failed to remove prepared transaction: " + xid + ". Reason: " + e);
    }
  }

  public void put(ActiveMQXid xid, Transaction transaction)
    throws XAException
  {
    String id = xid.toLocalTransactionId();
    byte[] data;
    try
    {
      data = xid.toBytes();
    }
    catch (Exception e)
    {
     
      throw new XAException("Failed to store prepared transaction: " + xid + ". Reason: " + e);
    }
    try
    {
      //byte[] data;
      Connection c = TransactionContext.getConnection();
      this.adapter.doAddXid(c, xid, data);
    } catch (SQLException e) {
      throw new XAException("Failed to store prepared transaction: " + xid + ". Reason: " + e);
    }
  }

  public void loadPreparedTransactions(TransactionManager transactionManager) throws XAException
  {
    try {
      Connection c = TransactionContext.getConnection();
      this.adapter.doLoadPreparedTransactions(c, transactionManager);
    } catch (SQLException e) {
      log.error("Failed to recover prepared transaction log: " + e, e);
      throw new XAException("Failed to recover prepared transaction log. Reason: " + e);
    }
  }

  public void start()
    throws JMSException
  {
  }

  public synchronized void stop()
    throws JMSException
  {
  }
}